home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / submit / submit_txt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  9.3 KB  |  490 lines

  1. /* submit_txt.c: handles the bodies of the messages */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/submit/RCS/submit_txt.c,v 6.0 1991/12/18 20:28:02 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/submit/RCS/submit_txt.c,v 6.0 1991/12/18 20:28:02 jpo Rel $
  9.  *
  10.  * $Log: submit_txt.c,v $
  11.  * Revision 6.0  1991/12/18  20:28:02  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "head.h"
  19. #include "list_bpt.h"
  20. #include "q.h"
  21. #include "chan.h"
  22. #include <isode/internet.h>
  23. #include <fcntl.h>
  24. #include <sys/stat.h>
  25.  
  26.  
  27. extern LIST_BPT        *bodies_all, *headers_all;
  28. extern int        privileged;
  29. extern char        *loc_dom_mta;
  30. extern char        *mgt_inhost;
  31. extern char        *msg_basedir;
  32. extern char        *msg_unique;
  33. extern char        *cont_p2;
  34. extern char        *cont_p22;
  35. extern int        submit_debug;
  36. extern char        msg_fullpath[];
  37. extern void        pro_reply ();
  38. extern void txt_mgt (), err_abrt();
  39.  
  40.  
  41. /* -- globals  -- */
  42. char            io_fpart[MAXPATHLENGTH];
  43. long            msg_size;
  44. int            numBps;
  45. int            forwMsg;
  46.  
  47. /* -- static variables -- */
  48. static FILE        *io_ofp;    /* -- output -- */
  49. static int        io_linkpart;    /* -- linked part so no txt copy -- */
  50. static char        *io_ostrend;
  51. static char        io_tfname[MAXPATHLENGTH];
  52.  
  53.  
  54. /* -- local routines -- */
  55. int            txt_tend();
  56. int            txt_init();
  57. void            txt_input();
  58. static int        txt_bptfind();
  59. static int        txt_pend();
  60. static int        txt_pinit();
  61. static int        txt_read();
  62. static void        txt_bp_check();
  63. static void        txt_in();
  64. static void        txt_via();
  65. static void        txt_in_debug();
  66.  
  67.  
  68.  
  69. /* ---------------------  Begin     Routines  -------------------------------- */
  70.  
  71.  
  72.  
  73.  
  74. void txt_input (qp, addvia)   /* -- control the text -- */
  75. Q_struct *qp;
  76. int    addvia;
  77. {
  78.     int        retval,
  79.             nparts = 0,
  80.             first = TRUE;
  81.     char lbuf[BUFSIZ];
  82.  
  83.     PP_TRACE (("txt_input()"));
  84.  
  85.     /* -- set up to recieve text -- */
  86.     if (rp_isbad (retval = txt_read (lbuf)))
  87.         err_abrt (retval, "Protocol failure");
  88.  
  89.     if ((retval = txt_init(qp)) != RP_OK)
  90.         err_abrt (retval, "Text initialisation");
  91.  
  92.     pro_reply (RP_OK, "base %s", io_tfname);
  93.  
  94.     while ((retval = txt_pinit(qp)) == RP_OK) {
  95.         PP_TRACE (("text loop"));
  96.         /* -- add 822 trace -- */
  97.         if (first && !io_linkpart && addvia)
  98.             txt_via (qp, io_ofp);
  99.         first = FALSE;
  100.         nparts++;
  101.         if (io_linkpart)
  102.             continue;
  103.         if (submit_debug)
  104.             txt_in_debug ();
  105.         else
  106.             txt_in();
  107.         if ((retval = txt_pend()) != RP_OK)
  108.             err_abrt (retval, "Text ending");
  109.     }
  110.  
  111.     if (rp_isbad (txt_tend()))
  112.         retval = RP_MECH;
  113.  
  114.     if (retval != RP_DONE)
  115.         err_abrt (RP_MECH, "Unknown error in txt_input");
  116.  
  117.     txt_mgt(qp);
  118. }
  119.  
  120.  
  121.  
  122.  
  123. int txt_tend()    /* -- finally finish -- */
  124. {
  125.     PP_TRACE (("txt_tend()"));
  126.  
  127.     if (io_ofp != NULLFILE) {
  128.         if(check_close (io_ofp) == NOTOK)
  129.             return RP_MECH;
  130.         io_ofp = NULLFILE;
  131.     }
  132.  
  133.     if (isstr (io_ostrend))
  134.         * (io_ostrend - 1) = '\0';
  135.     return RP_OK;
  136. }
  137.  
  138.  
  139.  
  140.  
  141. /* ----------------------  Static  Routines  -------------------------------- */
  142.  
  143.  
  144.  
  145.  
  146. int txt_init(qp)
  147. Q_struct *qp;
  148. {
  149.  
  150.     PP_TRACE (("txt_init ('%s', '%s')", msg_fullpath, msg_basedir));
  151.  
  152.     io_linkpart    = FALSE;
  153.     *io_fpart    = '\0';
  154.     msg_size    = 0;
  155.     qp -> msgsize = 0;
  156.     numBps    = 0;
  157.     forwMsg = 0;
  158.  
  159.     if (mkdir (msg_basedir, 0777) < 0)
  160.         err_abrt (RP_FIO, "Cannot create base dir %s", msg_basedir);
  161.  
  162.     (void) strcpy (io_tfname, msg_basedir);
  163.     (void) strcat (io_tfname, "/");
  164.  
  165.     /* -- make io_ostrend point to the end of the string. -- */
  166.     io_ostrend = io_tfname + strlen (io_tfname);
  167.     io_ofp = NULLFILE;
  168.  
  169.     return (RP_OK);
  170. }
  171.  
  172.  
  173.  
  174.  
  175. /* -- initialise for reading a single part of a msg -- */
  176. static int txt_pinit(qp)
  177. Q_struct *qp;
  178. {
  179.     char    lbuf[LINESIZE],
  180.         *splt;
  181.     int    retval;
  182.  
  183.     PP_DBG (("txt_pinit (%s)", io_tfname));
  184.  
  185.     io_linkpart = FALSE;    /* -- reset -- */
  186.  
  187.     if (rp_isbad (retval = txt_read (lbuf)))
  188.         return (retval);
  189.  
  190.     if (lbuf[0] == '\0')
  191.         return (RP_DONE);
  192.  
  193.     if ((splt = index (lbuf, ' ')) != NULL) {
  194.         *splt++ = '\0';
  195.         io_linkpart = TRUE;
  196.         if (!privileged)
  197.             err_abrt (RP_USER, "Mortals cannot link");
  198.     }
  199.  
  200.     if(rp_isbad (retval =  txt_psetup (qp, lbuf, splt)))
  201.         return retval;
  202.  
  203.     if (io_linkpart)
  204.         pro_reply (RP_OK, "linked the files");
  205.     else
  206.         pro_reply (RP_OK, "file is '%s'", io_tfname);
  207.  
  208.     return (RP_OK);
  209. }
  210.  
  211. int txt_psetup (qp, bp, linkfile)
  212. Q_struct *qp;
  213. char    *bp, *linkfile;
  214. {
  215.     char *p;
  216.     struct stat    statbuf;
  217.     int fd;
  218.  
  219.     txt_bp_check (qp, bp);
  220.  
  221.     (void) strcpy (io_ostrend, bp);
  222.  
  223.     /* make relevant directories */
  224.     for (p = io_ostrend; (p = index (p, '/')) != NULL; p++) {
  225.         *p = '\0';
  226.         (void) mkdir (io_tfname, 0777);
  227.         *p = '/';
  228.     }
  229.  
  230.  
  231.     if (io_linkpart) {
  232.         if (link (linkfile, io_tfname) < 0)
  233.             err_abrt (RP_FIO, "Cannot link file '%s' to '%s'",
  234.                   linkfile, io_tfname);
  235.  
  236.         if (*io_fpart == '\0')
  237.             (void) strcpy (io_fpart, io_tfname);
  238.  
  239.         /* -- check message size -- */
  240.         if (stat (io_tfname, &statbuf) >= 0)
  241.             msg_size += statbuf.st_size;
  242.         return (RP_OK);
  243.     }
  244.  
  245.  
  246.     if ((fd = open (io_tfname, O_CREAT | O_WRONLY | O_EXCL, 0644)) < 0)
  247.         err_abrt (RP_FIO, "Can't create file '%s'", io_tfname);
  248.  
  249.  
  250.     if ((io_ofp = fdopen (fd, "w")) == NULLFILE) {
  251.         (void) close (fd);
  252.         (void) unlink (io_tfname);
  253.         *io_tfname = '\0';
  254.         err_abrt (RP_FIO, "cannot open io_tfname");
  255.     }
  256.  
  257.  
  258.     if (*io_fpart == '\0')
  259.         (void) strcpy (io_fpart, io_tfname);
  260.     return RP_OK;
  261. }
  262.  
  263.  
  264.  
  265.  
  266. static int txt_pend()  /* -- end of the text input part -- */
  267. {
  268.     int retval;
  269.     PP_TRACE (("txt_pend()"));
  270.  
  271.     if (rp_isbad (retval = txt_pfinish ()))
  272.         return retval;
  273.     pro_reply (RP_OK, "got this text part");
  274.  
  275.     return (RP_OK);
  276. }
  277.  
  278. int txt_pfinish ()
  279. {
  280.     if (check_close (io_ofp) == NOTOK)
  281.         err_abrt (RP_FIO, "Can't write text to disk");
  282.     io_ofp = NULLFILE;
  283.     return RP_OK;
  284. }
  285.  
  286.  
  287. static void txt_in()  /* -- input the text -- */
  288. {
  289.     long    datalen;
  290.     long len;
  291.     char    buf[BUFSIZ];
  292.  
  293.     PP_TRACE (("txt_in()"));
  294.  
  295.     while ((int)fread ((char *)&datalen, sizeof (datalen), 1, stdin) > 0) {
  296.         datalen = ntohl (datalen);
  297.         if ((len = datalen) == 0)
  298.             return;
  299.         while (len > 0) {
  300.             int dlen, nc;
  301.  
  302.             dlen = len < sizeof (buf) ? len : sizeof (buf);
  303.             nc = fread (buf, sizeof (buf[0]), dlen, stdin);
  304.             if (nc <= 0)
  305.                 err_abrt (RP_FIO, "Read error");
  306.             if (rp_isbad(txt_write (buf, nc)))
  307.                 err_abrt (RP_FIO, "Data copy failed");
  308.             len -= nc;
  309.         }
  310.         PP_DBG (("submit/txt_in copied %d bytes",datalen));
  311.     }
  312. }
  313.  
  314. int txt_write (bp, nc)
  315. char    *bp;
  316. int    nc;
  317. {
  318.     msg_size += nc;
  319.     if (fwrite (bp, sizeof (*bp), nc, io_ofp) != nc)
  320.         return RP_FIO;
  321.     return RP_OK;
  322. }
  323.  
  324.  
  325. static int txt_from_file (file)
  326. char *file;
  327. {
  328.     char *cp;
  329.     FILE *fp;
  330.     char    buf[BUFSIZ];
  331.     int n;
  332.  
  333.     file ++;
  334.     if ((cp = index(file, '\n')) != NULLCP)
  335.         *cp = 0;
  336.     if ((fp = fopen (file, "r")) == NULL) {
  337.         PP_LOG (LLOG_EXCEPTIONS, ("No such file %s", file));
  338.         return NOTOK;
  339.     }
  340.  
  341.     while ((n = fread (buf, 1, sizeof buf, fp)) > 0)
  342.         if (rp_isbad (txt_write (buf, n)))
  343.             err_abrt (RP_FIO, "Copy failed");
  344.     return OK;
  345. }
  346.  
  347. static void txt_in_debug ()  /* -- input the text -- */
  348. {
  349.     char buf[BUFSIZ];
  350.     int n;
  351.     int first = 1;
  352.     PP_TRACE (("txt_in_debug ()"));
  353.  
  354.     while (fgets (buf, sizeof buf, stdin) && strcmp(buf, ".\n") != 0) {
  355.         if (first && *buf == '<' && txt_from_file(buf) == OK)
  356.             return;
  357.         first = 0;
  358.         msg_size += n = strlen(buf);
  359.         if (rp_isbad(txt_write (buf, n)))
  360.             err_abrt (RP_FIO, "data copy failed");
  361.     }
  362. }
  363.  
  364. static int txt_read (buf)  /* -- read the control flow -- */
  365. char    *buf;
  366. {
  367.     register int    c;
  368.     register char    *p;
  369.  
  370.     PP_TRACE (("txt_read()"));
  371.     for (p = buf; (c = getc (stdin)) != EOF && c != '\n'; *p++ = c)
  372.         continue;
  373.     *p = '\0';
  374.     PP_DBG (("text_read - read '%.10s'", buf));
  375.     return ((c == EOF) ? RP_EOF : RP_OK);
  376. }
  377.  
  378.  
  379.  
  380.  
  381. static void txt_via (qp, fp)
  382. Q_struct *qp;
  383. FILE    *fp;
  384. {
  385.     char    buf[BUFSIZ];
  386.     char    thedate[LINESIZE];
  387.     char    showstr[BUFSIZ];
  388.     UTC    ut, lt;
  389.     extern UTC utclocalise();
  390.     CHAN    *ch_in;
  391.  
  392.     ut = utcnow();
  393.     lt = utclocalise(ut);
  394.     (void) UTC2rfc(lt, thedate);
  395.     free ((char *)ut);
  396.     free ((char *)lt);
  397.  
  398.     ch_in = qp -> inbound -> li_chan;
  399.  
  400.     if (ch_in -> ch_trace_type == CH_TRACE_VIA)
  401.         (void) sprintf (buf, "Via: %s; %s\n",
  402.                 loc_dom_mta, thedate);
  403.     else {
  404.         if ( ch_in -> ch_show && 
  405.              (strncmp (ch_in -> ch_show, "via", 3) == 0
  406.              || strncmp (ch_in -> ch_show, "with", 4) == 0)) {
  407.             (void) strcpy (showstr, " ");
  408.             (void) strcat (showstr, ch_in -> ch_show);
  409.         }
  410.         else showstr[0] = '\0';
  411.             
  412.         (void) sprintf (buf, "Received: from %s by %s%s id <%s@%s>; %s\n",
  413.                 mgt_inhost, loc_dom_mta,
  414.                 showstr,
  415.                 msg_unique + 4, loc_dom_mta,
  416.                 thedate);
  417.     }
  418.     fputs (buf, fp);
  419. }
  420.  
  421.  
  422.  
  423.  
  424. static void txt_bp_check (qp, file)
  425. Q_struct *qp;
  426. char    *file;
  427. {
  428.     char        *p;
  429.     
  430.     if (*file == '/')
  431.         err_abrt (RP_PARM, "File has full pathname %s", file);
  432.  
  433.     if ((p = index (file, '/')) != NULLCP) {
  434.         if (!isdigit (*file) || strncmp (p - 4, ".ipm", 4) != 0)
  435.             err_abrt (RP_PARM, "Not a forwarded message %s", file);
  436.         txt_bp_check (qp, ++p);
  437.         forwMsg++;
  438.         return;
  439.     }
  440.  
  441.  
  442.     /* -- check against content types -- */
  443.     if (strcmp (file, cont_p2) == 0
  444.         || strcmp (file, cont_p22) == 0
  445.         || (isstr(qp->cont_type) && strcmp (file, qp->cont_type) == 0))
  446.         return; 
  447.  
  448.     if (isdigit (*file)) {
  449.         for (p = file + 1; isdigit (*p); p++)
  450.             continue;
  451.         if (*p != '.')
  452.             err_abrt (RP_PARM, "Bad filename syntax %s", file);
  453.         p++;
  454.     }
  455.     else    p = file;
  456.  
  457.  
  458.  
  459.     /* -- check if this body part is allowed -- */
  460.  
  461.     if (!txt_bptfind (bodies_all, p)
  462.         && !txt_bptfind(headers_all, p))
  463.         err_abrt (RP_PARM, "Unknown body part '%s'", file);
  464.  
  465.  
  466.  
  467.     /* -- check the file against the list of eits in Q -- */
  468.  
  469.     if (!txt_bptfind (qp->encodedinfo.eit_types, p))
  470.         err_abrt (RP_PARM, 
  471.             "'%s' is not specified in the orig encoded info", file);
  472.  
  473.     numBps++;
  474.     return;
  475. }
  476.  
  477.  
  478.  
  479.  
  480. static int txt_bptfind (list, item)
  481. LIST_BPT    *list;
  482. char        *item;
  483. {
  484.  
  485.     if (list_bpt_nfind (list, item, strlen(item)))
  486.         return TRUE;
  487.  
  488.     return FALSE;
  489. }
  490.